  float4x4 worldViewProjection : WorldViewProjection;
  float4x4 worldInverseTranspose : WORLDINVERSETRANSPOSE;
  
  sampler normalSampler;
  int hasNormalSampler;

  struct VertexShaderInput {
    float4 normal : NORMAL;
    float4 position : POSITION;
  	float4 tangent : TANGENT;
  	float4 binormal : BINORMAL;
    float2 tex :TEXCOORD0;
  };
	
  struct PixelShaderInput{
    float4 position : POSITION;
    float2 tex : TEXCOORD0;
  	float3 normal :TEXCOORD1;
  	float3 binormal : TEXCOORD2;
  	float3 tangent : TEXCOORD3;
  };

  PixelShaderInput vertexShaderFunction(VertexShaderInput input) {
    PixelShaderInput output;
    output.position = mul(input.position, worldViewProjection);
    output.tex = input.tex;
    output.normal = mul(input.normal, worldInverseTranspose).xyz;
  	output.binormal = mul(input.binormal, worldInverseTranspose).xyz;
  	output.tangent = mul(input.tangent, worldInverseTranspose).xyz;
    return output;
  }

  float4 pixelShaderFunction(PixelShaderInput input): COLOR {
  	float3 normal;
  	if(hasNormalSampler){
		 // Construct a transform from tangent space into world space.
		float3x3 tangentToWorld = float3x3(input.tangent,
		                                     input.binormal,
		                                     input.normal);
  		normal = tex2D(normalSampler, input.tex).xyz - float3(0.5, 0.5, 0.5);
  		normal = mul(normal, tangentToWorld);
  	}else{
  		normal = normalize(input.normal);
  	}
  	normal = normal *0.5 + 0.5;
    return float4(normal, 1);
  }

  // #o3d VertexShaderEntryPoint vertexShaderFunction
  // #o3d PixelShaderEntryPoint pixelShaderFunction
  // #o3d MatrixLoadOrder RowMajor